\chapter{无监督学习}
\label{chap:unsupervised}
机器学习主要分为三类：监督学习（supervised Learning）、增强学习（reinforcement learning）、无监督学习（unsupervised
learning）。也存在半监督学习（semi-supervised learning）这种情况，但在此不予讨论。

简单来说，区分监督学习和无监督学习的方法就是输入数据是否有标签（label）。
如若没有标签则为无监督学习。
我们以机器学习中的分类（classfication）算法来举例，
对于分类算法来说，输入的训练数据有特征（feature），有标签（label）。
所谓的学习，其本质就是找到特征和标签间的关系（mapping）。
而去判断一个分类算法的成功与否的方法，便是当我们输入有特征无标签的未知数据时，
能否通过已知关系（参数）得到未知数据标签。

举个简单的例子，有监督学习相当于刷算法题的时候你知道答案，
而无监督学习相当于你根本就没有答案，只能靠自己摸索。
所以，与我们的常识相符，无监督学习的准确度往往比起有监督学习要低得多。
那也许你会问了，既然无监督学习准确度那么低，为什么我们还要用它呢？
那是因为在实际情况下，标签的获取需要极大的人工量，还不能保证变迁的准确性。
所以，无监督学习也是十分重要的。

\section{聚类算法}
聚类是数据挖掘中的概念，其定义为按照某个标准把一个数据集分隔成不同的类或簇，
使得相同类里的数据相似程度尽可能大。反之，不在同一个类里的数据，
其差异也要尽可能大。“物以类聚，人以群分”就能大概指代聚类算法的意思。

讲到这里，我们需要区分聚类(clustering)与分类(classification)之间的区别。
对于聚类来说，我们在聚类时，并不关心其中某一类是什么，我们需要实现的目标只是把
相似的东西分到一起。因此，对于聚类算法来说，只要知道相似度衡量的标准就可以开始训练了。
与之相对的，分类算法需要你告知它，它需要将数据分成哪些具体的类别，
所以分类算法需要从训练集中进行学习，从而明白如何对未知数据进行分类。
这就是聚类和分类的区别。

聚类的步骤主要如下：
1.数据准备：将数据转换为标准输入形式，使用特征标准化等方法；
2.特征选择：从最初的特征中选择最有效的特征,并将其存储于向量中；
3.特征提取：通过对所选择的特征进行转换，得到新的重点特征；
4.聚类：首先选择合适特征类型的某种距离函数进行接近程度的度量，而后执行聚类或分组；
5.聚类结果评估：对聚类结果进行评估，评估主要分为3种：外部有效性评估、内部有效性评估和相关性测试评估。

聚类主要分为层次化聚类算法，划分式聚类算法，基于密度的聚类算法，基于网格的聚类算法，基于模型的聚类算法等。
下面我们就挑出几个重要的算法为大家进行讲解。

\subsection{K-means算法}
K-Means算法的特点是类别的个数是人为给定的，
其假设数据之间的相似度可以使用欧氏距离度量，
如果不能使用欧氏距离度量，要先把数据转换到能用欧氏距离度量。

接下来，我们简单介绍一下流程：
首先，我们有在n维向量当中的一堆点，这里以二维空间为例。

%图片

接着我们随机生成k个聚类中心点，相当于将其分为几个类别。
然后分别计算每一个数据点到这些中心的距离，把距离最短的那个当成自己的类别。
这样就可以发现每个点都已经被分类了(有一个中心点)，但是并不准确。

%图片

接下来就是无监督学习，使得分类变得更加准确的时候。
我们一开始随机确定的分类点，这时候就要变化了。
而它变化的标准就是“收复”附近的点，所以它将往所有它这一类别的点的坐标平均值移动，
也就是移向中心。而到达中心后，将再一次判断各个点到k个中心点的距离，
选取离每个点最近的中心点作为它的类别，以此类推。

%图片

伪代码流程如下所示：
\begin{lstlisting}[language=Java]
public static double K-Means(输入数据，中心点个数K){
    获取输入数据的维度Dim和个数N
    随机生成K个Dim维的点
    while(算法未收敛){
        对N个点：计算每个点属于哪一类。
        对于K个中心点：
            1，找出所有属于自己这一类的所有数据点
            2，把自己的坐标修改为这些数据点的中心点坐标
    }
    return 结果
}
\end{lstlisting}

接下来，我们来说明一下k-means算法使用过程中有可能会遇到的问题。
1.测量距离的方法
并非一定要使用欧氏空间这个方法，只需满足以下条件都可以用：
首先有个分类两个点的方法的算符记作$$<\vec{a}, \vec{b}>$$，
并且其具有交换性$<\vec{a}, \vec{b}>=<\vec{b}, \vec{a}>$。
其次需要可以求一堆点的平均值的算法(求中心点)：
$\vec{\mu}=\operatorname{Mean}\left(\overrightarrow{a_{1}}, \ldots, \overrightarrow{a_{n}}\right)$
求出后只需满足：$\sum_{i=1}^{n}\left(\vec{\mu}-\overrightarrow{a_{i}}\right)^{2}$。

2.如何知道是否收敛？
使用代价函数：$\tilde{J}=\sum_{i=1}^{C} \sum_{j=1}^{N} r_{i j} \times \nu\left(x_{j}, \mu_{i}\right)$。
其中：$\nu\left(x_{j}, \mu_{i}\right)=\left\|x_{j}-\mu_{i}\right\|^{2}$。
代价函数的差分值小于一定数值的时候(N次越不过最小值点)即可认为是收敛了。

3.代价函数不收敛，怎么办？
首先说一下什么时候容易发生震荡：
在数据点个数比较少而且比较稀疏的时候容易发生这种事情，发生的原因大约有两种常见的：
1、陷入某个环里，然后开始震荡，它将会绕着中心点进行低频振荡。
2、两个点互相交换，每次交换不改变J的值就收敛了，
如果交换以后不幸影响了其它的点，就出现了高频振荡。
这个时候给出一种简单的解决方案：阻尼。
简而言之，就是更新自己位置的时候考虑一下原来的位置，
一般阻尼比（在0~1之间取值）决定收敛速度，收敛的慢了也就不容易震荡，
也就越容易陷入局部极小值，也就是说，不震荡的情况下我们应该把阻尼比尽可能取小一点
$\vec{C}^{u p d}=\vec{C}^{n e w} \times(1-\xi)+\vec{C}^{o l d} \times \xi$
$\vec{C}^{u p d}$是最后中心点的取值，$\vec{C}^{n e w}$是当前集合的中心点，
$\vec{C}^{o l d}$是原来的中心点坐标。

\subsection{DBScan算法}

\section{DL4J示例}